
#include "drv_adc.h"

volatile uint16_t adc_value[ADC_CHANNEL_NUM];

static const adc_gpio gpio_list[ADC_CHANNEL_NUM] = {
	{RV1_PIN, RV1_PORT},
	{RV2_PIN, RV2_PORT},
	{RV3_PIN, RV3_PORT},
};

/**
* @ Description:adc通道的GPIO配置
* @param none - 无.
* @return none - 无.
*/
static void adc_gpio_cfg(void)
{
	GPIO_InitTypeDef gpio_init;
	const adc_gpio *pgpio = NULL;
	adc_gpio_clkopen();
    GPIO_StructInit(&gpio_init);
    
    gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
    gpio_init.GPIO_Mode = GPIO_Mode_AIN;
	for (pgpio = gpio_list; pgpio < &gpio_list[ADC_CHANNEL_NUM]; pgpio++)
	{
		gpio_init.GPIO_Pin = pgpio->pin;
		GPIO_Init(pgpio->gpio, &gpio_init);	
	}
}

/**
* @ Description:adc外设配置
* @param adc - 待初始化的外设. 头文件中有对应宏定义
* @param adc_channel_x - ADC通道. 头文件中有对应宏定义
* @return none - 无.
*/
static void adc_module_cfg(ADC_TypeDef * adc, ADCCHANNEL_TypeDef adc_channel_x, uint16_t rank)
{
	/* 与ADC外设有关的初始化 */
    ADC_InitTypeDef adc_init;
    ADC_StructInit(&adc_init);
	RCC_APB2PeriphClockCmd(RCC_APB2ENR_ADC1, ENABLE);
    adc_init.ADC_Resolution = ADC_Resolution_12b;
    adc_init.ADC_PRESCARE	= ADC_PCLK2_PRESCARE_12;
    adc_init.ADC_Mode 		= ADC_Mode_Continue;
    adc_init.ADC_DataAlign 	= ADC_DataAlign_Right;
    adc_init.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
    ADC_Init(adc, &adc_init);
	
	/* 转换序列设置 */
    ADC_RegularChannelConfig(adc, adc_channel_x, rank, ADC_Samctl_7_5);
}

static void adc_dma_cfg(void)
{
    DMA_InitTypeDef dma_init;

    RCC_AHBPeriphClockCmd(RCC_AHBENR_DMA1, ENABLE);
    DMA_DeInit(DMA1_Channel1);
    DMA_StructInit(&dma_init);
	
    dma_init.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->DR);
    dma_init.DMA_MemoryBaseAddr		= (uint32_t)adc_value;
    dma_init.DMA_DIR 				= DMA_DIR_PeripheralSRC;
    dma_init.DMA_BufferSize 		= ADC_CHANNEL_NUM;
    dma_init.DMA_PeripheralInc 		= DMA_PeripheralInc_Disable;
    dma_init.DMA_MemoryInc 			= DMA_MemoryInc_Enable;
    dma_init.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    dma_init.DMA_MemoryDataSize 	= DMA_MemoryDataSize_HalfWord;
    dma_init.DMA_Mode 				= DMA_Mode_Circular;
    dma_init.DMA_Priority 			= DMA_Priority_High;
    dma_init.DMA_M2M 				= DMA_M2M_Disable;
    dma_init.DMA_Auto_reload 		= DMA_Auto_Reload_Disable;
    DMA_Init(DMA1_Channel1, &dma_init);
    DMA_Cmd(DMA1_Channel1, ENABLE);
}

#ifdef ADC_ADWG
/**
* @ Description:adc模拟看门狗配置
* @param adc - 待初始化的外设.
* @param adc_channel_x - ADC通道.
* @return none - 无.
*/
static void adc_awdg_cfg(ADC_TypeDef * adc, ADCCHANNEL_TypeDef adc_channel_x)
{
	/* 模拟看门狗功能。当转换值超出设定的阈值区间时，若ADC_ADCR.AWDIE 置位，则产生中断 */
    ADC_AnalogWatchdogCmd(adc, ENABLE);
    ADC_AnalogWatchdogThresholdsConfig(adc, 3000, 1500);
    ADC_AnalogWatchdogSingleChannelConfig(adc, adc_channel_x);
}

/**
* @ Description:nvic配置
* @param none - 无.
* @return none - 无.
*/
static void adc_nvic_cfg(void)
{
    NVIC_InitTypeDef nvic_init;
    nvic_init.NVIC_IRQChannel = ADC1_2_IRQn;
    nvic_init.NVIC_IRQChannelPreemptionPriority = 0;
    nvic_init.NVIC_IRQChannelSubPriority = 2;
    nvic_init.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&nvic_init);
	ADC_ITConfig(ADC_USE, ADC_IT_AWD, ENABLE);
}
#endif

/**
* @ Description:adc初始化对外接口
* @param none - 无.
* @return none - 无.
*/
void adc_init(void)
{
	adc_gpio_cfg();
	adc_module_cfg(ADC_USE, RV1_CHARNNEL, 0);
	adc_module_cfg(ADC_USE, RV2_CHARNNEL, 1);
	adc_module_cfg(ADC_USE, RV3_CHARNNEL, 2);
	adc_dma_cfg();
	ADC_DMACmd(ADC_USE, ENABLE);
    ADC_Cmd(ADC_USE, ENABLE);
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}

